package com.wkq.net.work

import android.content.Context
import android.util.Log
import androidx.work.BackoffPolicy
import androidx.work.Constraints
import androidx.work.Data
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.wkq.net.util.DownSecretUtil
import java.io.File
import java.util.UUID
import java.util.concurrent.TimeUnit

/**
 *
 *@Author: wkq
 *
 *@Time: 2025/6/30 11:03
 *
 *@Desc:  批量下载文件
 */
object WorkManagerUtil {
    /**
     * 下载列表
     */
    fun downList(mContext: Context, downList: List<WorkDownInfo>,onStatusChanged: ((url: String, state: WorkInfo.State, filePath: String?) -> Unit)? = null) {
//        cancelAllWork(mContext)
        val downloadRequests = mutableListOf<OneTimeWorkRequest>()
        val workManager = WorkManager.getInstance(mContext)
        val requestMap = mutableMapOf<UUID, String>()
        downList.forEach {
            val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
            val oneTimeWorkRequest = OneTimeWorkRequest.Builder(ResourceDownloadWorker::class.java)
                .setConstraints(constraints)
                // 重试
                .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1000, TimeUnit.MILLISECONDS)
                .setInputData(bulidData(it.url, it.dirFilePath,it.id,it.fileName)).build()
            requestMap[oneTimeWorkRequest.id] = it.url
            downloadRequests.add(oneTimeWorkRequest)
        }
        if (downloadRequests.size>0){

            workManager .enqueue(downloadRequests)

            downloadRequests.forEach { request ->
                workManager.getWorkInfoByIdLiveData(request.id).observeForever { info ->
                    val url = requestMap[request.id] ?: return@observeForever
                    val state = info.state
                    if (state==WorkInfo.State.SUCCEEDED){
                        Log.e("下载:","成功-->"+url)
                        val filePath = info.outputData.getString("path")
                        val id = info.outputData.getString("id")?:""
                        onStatusChanged?.invoke(id, state, filePath)
                    }else if (state==WorkInfo.State.FAILED){
                        Log.e("下载:","失败-->"+url)
                    }

                }
            }

        }

    }

    /**
     * 下载单个
     */
    fun downOne(mContext: Context, url: String, dirFilePath: String,id: String?,fileName: String="",onStatusChanged: ((url: String, state: WorkInfo.State, filePath: String?) -> Unit)? = null) {
        // 设置任务约束条件
        val workManager = WorkManager.getInstance(mContext)
        if (!isExist(url, dirFilePath)) {
            // 联网约束
            val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
            val oneTimeWorkRequest = OneTimeWorkRequest.Builder(ResourceDownloadWorker::class.java)
                .setConstraints(constraints).setInputData(bulidData(url, dirFilePath,id!!,fileName)).build()
           val requestId= oneTimeWorkRequest.id
           workManager.enqueue(oneTimeWorkRequest)

            workManager.getWorkInfoByIdLiveData(requestId).observeForever { info ->
                val state = info.state
                if (state==WorkInfo.State.SUCCEEDED){
                    val filePath = info.outputData.getString("path")
                    val id = info.outputData.getString("id")?:""
                    onStatusChanged?.invoke(id, state, filePath)
                }
            }
        }
    }

    private fun bulidData(url: String, dirFilePath: String,id: String, fileName: String=""): Data {
        return Data.Builder()
            .putString("id",id)
            .putString("url", url)
            .putString("fileName", fileName)
            .putString("rootPath", dirFilePath)
            .build()
    }

    fun cancelAllWork(mContext: Context) {
        WorkManager.getInstance(mContext).cancelAllWork()
    }

 private   fun cancelAllWork(mContext: Context, uid: UUID) {
        WorkManager.getInstance(mContext).cancelWorkById(uid)
    }

    /**
     * 文件是否存在
     */
    fun isExist(url: String?, dirFilePath: String?): Boolean {
        if (dirFilePath.isNullOrEmpty() || url.isNullOrEmpty()) return false
        val fileName = DownSecretUtil.getMD5Result(url)
        return File(dirFilePath, fileName).exists()
    }

    fun isUrlToPath(url: String?, dirFilePath: String?): String {
        if (dirFilePath.isNullOrEmpty() || url.isNullOrEmpty()) return url?:""
        val fileName = DownSecretUtil.getMD5Result(url)
        return dirFilePath+ File.separator+fileName
    }

}